import { ParsedExcelFile } from './excel-parser.server';

export interface EntityObject {
  name: string;
  code?: string;
  category?: string;
  standardName?: string;
  standardCode?: string;
  attributes?: string[];
  level?: string;
  description?: string;
}

export interface ClassificationStandard {
  code: string;
  name: string;
  level: string;
  parentCode?: string;
  attributes: string[];
  description?: string;
}

export interface ParameterDefinition {
  name: string;
  type: string;
  required: boolean;
  description?: string;
  defaultValue?: any;
}

export interface GeneratedParameterTable {
  objectName: string;
  objectCode: string;
  standardCode: string;
  standardName: string;
  namingParameters: {
    [key: string]: any;
  };
  locationParameters: {
    [key: string]: any;
  };
  basicParameters: {
    [key: string]: any;
  };
}

export class ExcelAnalyzer {
  private classificationData: ParsedExcelFile | null = null;
  private comparisonData: ParsedExcelFile | null = null;
  private standards: ClassificationStandard[] = [];
  private entities: EntityObject[] = [];

  constructor(classificationData: ParsedExcelFile, comparisonData: ParsedExcelFile) {
    this.classificationData = classificationData;
    this.comparisonData = comparisonData;
    this.analyzeData();
  }

  private analyzeData() {
    this.extractStandards();
    this.extractEntities();
  }

  // 从01015规范表中提取标准分类信息
  private extractStandards() {
    if (!this.classificationData) return;

    this.standards = [];
    
    // 查找主分类表（通常在第一个工作表）
    const mainSheet = this.classificationData.sheets[0];
    if (!mainSheet) return;

    const headers = mainSheet.headers;
    
    // 查找关键列
    const codeIndex = headers.findIndex(h => 
      h.includes('代码') || h.includes('编码') || h.includes('Code') || h.includes('编号')
    );
    const nameIndex = headers.findIndex(h => 
      h.includes('名称') || h.includes('类别') || h.includes('分类') || h.includes('Name')
    );
    const levelIndex = headers.findIndex(h => 
      h.includes('级别') || h.includes('层级') || h.includes('Level')
    );
    const descIndex = headers.findIndex(h => 
      h.includes('说明') || h.includes('描述') || h.includes('备注')
    );

    mainSheet.rows.forEach((row, index) => {
      if (row && row.length > 0) {
        const code = codeIndex >= 0 ? row[codeIndex]?.toString().trim() : '';
        const name = nameIndex >= 0 ? row[nameIndex]?.toString().trim() : '';
        
        if (code && name) {
          const standard: ClassificationStandard = {
            code,
            name,
            level: levelIndex >= 0 ? row[levelIndex]?.toString() || '1' : '1',
            description: descIndex >= 0 ? row[descIndex]?.toString() : undefined,
            attributes: []
          };

          // 根据代码长度判断父级关系
          if (code.length > 2) {
            standard.parentCode = code.substring(0, code.length - 2);
          }

          this.standards.push(standard);
        }
      }
    });

    // 分析C开头的属性表
    this.classificationData.sheets.forEach(sheet => {
      if (sheet.sheetName.startsWith('C') || sheet.sheetName.includes('属性')) {
        this.extractAttributesFromSheet(sheet);
      }
    });
  }

  // 从属性表中提取属性信息
  private extractAttributesFromSheet(sheet: any) {
    const headers = sheet.headers;
    const codeIndex = headers.findIndex((h: string) => 
      h.includes('代码') || h.includes('编码')
    );
    const attrIndex = headers.findIndex((h: string) => 
      h.includes('属性') || h.includes('参数') || h.includes('字段')
    );

    if (codeIndex >= 0 && attrIndex >= 0) {
      sheet.rows.forEach((row: any[]) => {
        if (row && row.length > 0) {
          const code = row[codeIndex]?.toString().trim();
          const attr = row[attrIndex]?.toString().trim();
          
          if (code && attr) {
            const standard = this.standards.find(s => s.code === code);
            if (standard) {
              standard.attributes.push(attr);
            }
          }
        }
      });
    }
  }

  // 从对比表中提取实体对象
  private extractEntities() {
    if (!this.comparisonData) return;

    this.entities = [];
    
    const sheet = this.comparisonData.sheets[0];
    if (!sheet) return;

    const headers = sheet.headers;
    
    // 查找相关列
    const nameIndex = headers.findIndex(h => 
      h.includes('实体对象') || h.includes('设备名称') || h.includes('名称') || 
      h.includes('对象') || h.includes('设备')
    );
    const codeIndex = headers.findIndex(h => 
      h.includes('编码') || h.includes('代码') || h.includes('编号')
    );
    const categoryIndex = headers.findIndex(h => 
      h.includes('分类') || h.includes('类别') || h.includes('类型')
    );
    const standardIndex = headers.findIndex(h => 
      h.includes('标准') || h.includes('规范') || h.includes('对应')
    );
    const standardCodeIndex = headers.findIndex(h => 
      h.includes('标准代码') || h.includes('规范代码') || h.includes('标准编码')
    );

    sheet.rows.forEach((row, index) => {
      if (row && row.length > 0) {
        const name = nameIndex >= 0 ? row[nameIndex]?.toString().trim() : '';
        
        if (name && name !== '' && !name.includes('序号') && !name.includes('编号')) {
          const entity: EntityObject = {
            name,
            code: codeIndex >= 0 ? row[codeIndex]?.toString().trim() : undefined,
            category: categoryIndex >= 0 ? row[categoryIndex]?.toString().trim() : undefined,
            standardName: standardIndex >= 0 ? row[standardIndex]?.toString().trim() : undefined,
            standardCode: standardCodeIndex >= 0 ? row[standardCodeIndex]?.toString().trim() : undefined,
          };

          // 尝试匹配标准分类
          const matchedStandard = this.findMatchingStandard(entity);
          if (matchedStandard) {
            entity.standardCode = matchedStandard.code;
            entity.standardName = matchedStandard.name;
            entity.attributes = [...matchedStandard.attributes];
          }

          this.entities.push(entity);
        }
      }
    });
  }

  // 查找匹配的标准分类
  private findMatchingStandard(entity: EntityObject): ClassificationStandard | null {
    // 首先尝试精确匹配
    if (entity.standardCode) {
      const exact = this.standards.find(s => s.code === entity.standardCode);
      if (exact) return exact;
    }

    // 然后尝试名称匹配
    if (entity.standardName) {
      const nameMatch = this.standards.find(s => 
        s.name.includes(entity.standardName!) || entity.standardName!.includes(s.name)
      );
      if (nameMatch) return nameMatch;
    }

    // 最后尝试分类匹配
    if (entity.category) {
      const categoryMatch = this.standards.find(s => 
        s.name.includes(entity.category!) || entity.category!.includes(s.name.substring(0, 4))
      );
      if (categoryMatch) return categoryMatch;
    }

    return null;
  }

  // 生成参数表
  public generateParameterTables(): GeneratedParameterTable[] {
    return this.entities.map(entity => {
      const matchedStandard = this.findMatchingStandard(entity);
      
      return {
        objectName: entity.name,
        objectCode: entity.code || this.generateObjectCode(entity),
        standardCode: entity.standardCode || matchedStandard?.code || 'UNKNOWN',
        standardName: entity.standardName || matchedStandard?.name || '未匹配标准',
        
        namingParameters: {
          '实体对象名称': entity.name,
          '对象编码': entity.code || this.generateObjectCode(entity),
          '标准代码': entity.standardCode || matchedStandard?.code || '',
          '标准名称': entity.standardName || matchedStandard?.name || '',
          '分类编码': this.getCategoryCode(entity),
          '命名规则': this.generateNamingRule(entity),
        },

        locationParameters: {
          '建筑物': '待填写',
          '楼层': '待填写',
          '房间': '待填写',
          '具体位置': '待填写',
          '安装位置编码': this.generateLocationCode(entity),
          '坐标信息': '待填写',
          '所属系统': '待填写',
          '管理单位': '待填写',
        },

        basicParameters: {
          '设备编码': entity.code || this.generateObjectCode(entity),
          '设备名称': entity.name,
          '设备分类': entity.category || '待填写',
          '标准名称': entity.standardName || matchedStandard?.name || '待填写',
          '制造商': '待填写',
          '型号': '待填写',
          '规格参数': '待填写',
          '技术指标': '待填写',
          '安装日期': '待填写',
          '投运日期': '待填写',
          '设备状态': '正常',
          '运行状态': '待填写',
          '维护周期': '待填写',
          '上次维护日期': '待填写',
          '下次维护日期': '待填写',
          '责任人': '待填写',
          '联系方式': '待填写',
          '备注信息': '待填写',
          // 添加标准要求的属性
          ...this.generateStandardAttributes(entity, matchedStandard),
        }
      };
    });
  }

  // 生成对象编码
  private generateObjectCode(entity: EntityObject): string {
    const prefix = entity.category ? entity.category.substring(0, 2).toUpperCase() : 'OBJ';
    const timestamp = Date.now().toString().slice(-6);
    return `${prefix}${timestamp}`;
  }

  // 获取分类编码
  private getCategoryCode(entity: EntityObject): string {
    if (entity.standardCode) return entity.standardCode;
    if (entity.category) {
      const matchedStandard = this.standards.find(s => s.name.includes(entity.category!));
      return matchedStandard?.code || 'CAT001';
    }
    return 'CAT001';
  }

  // 生成命名规则
  private generateNamingRule(entity: EntityObject): string {
    return `${entity.category || '分类'}+${entity.name.includes('阀') ? '阀门' : '设备'}+编号`;
  }

  // 生成位置编码
  private generateLocationCode(entity: EntityObject): string {
    return `LOC-${entity.code || Date.now().toString().slice(-4)}`;
  }

  // 生成标准属性
  private generateStandardAttributes(entity: EntityObject, standard: ClassificationStandard | null): any {
    if (!standard || !standard.attributes.length) return {};

    const attributes: any = {};
    standard.attributes.forEach(attr => {
      attributes[attr] = '待填写';
    });

    return attributes;
  }

  // 获取所有实体对象
  public getEntities(): EntityObject[] {
    return this.entities;
  }

  // 获取所有标准分类
  public getStandards(): ClassificationStandard[] {
    return this.standards;
  }

  // 获取匹配统计
  public getMatchingStats() {
    const totalEntities = this.entities.length;
    const matchedEntities = this.entities.filter(e => this.findMatchingStandard(e) !== null).length;
    
    return {
      totalCount: totalEntities,
      matchedCount: matchedEntities,
      unmatchedCount: totalEntities - matchedEntities,
      matchRate: totalEntities > 0 ? (matchedEntities / totalEntities * 100).toFixed(1) : '0'
    };
  }
} 